#pragma once
// 进行报文的解析

#include <iostream>
#include "Connection.hpp"
#include "Protocol.hpp"
#include "CalCulate.hpp"

using namespace protocol_ns;

class PackgeParse
{
public:
    static void Parse(Connection *conn)
    {
        // std::cout << "inbuffer: " << conn->Inbuffer() << std::endl;
        // 2. 分析数据
        std::string package;
        Request req;
        Calculate cal;
        while (true)
        {
            package = Decode(conn->Inbuffer());
            // std::cout << "inbuffer" << inbuffer << std::endl;
            if (package.empty())
                break;

            std::cout << "------------------begin-------------------" << std::endl;

            std::cout << "resq string: \n"
                      << package << std::endl;

            // 走到这里一定读到了完整的数据json串
            // 3. 反序列化
            req.Deserialize(package);

            // 4. 业务处理
            Response resp = cal.Excute(req);

            // 5. 对应答序列化
            std::string send_str;
            resp.Serialize(&send_str);

            std::cout << "resp Serialize:" << std::endl;
            std::cout << send_str << std::endl;
            // 6. 添加长度报头
            send_str = Encode(send_str);
            std::cout << "resp Encode:" << std::endl;
            std::cout << send_str << std::endl;
            
            // 将数据写入Connection中的outbuffer中
            conn->AppendOutBuffer(send_str);
        }
        // 到这里就可以发数据了

        if (!conn->OutBufferEmpty())
        {
            // 直接发数据，不用写入epoll中，因为默认写事件是有空间的
            if (conn->_sender != nullptr)
            {
                // conn->_sender(conn);

                // 也可直接打开写事件，因为一旦打开写事件，EPOLLOUT就会自动触发一次
                conn->_R->EnableReadWrite(conn->Sockfd(), true, true);// 开启对读事件关心
            }
        }
    }
};